import { isObject, ShapeFlags } from '@/shared'
import { createComponentInstance, setupComponent } from './component'

export function render(vnode, container) {
  patch(vnode, container)
}

function patch(vnode, container) {
  const { type, shapeFlag } = vnode
  if (shapeFlag & ShapeFlags.ELEMENT) {
    processElement(vnode, container)
  } else if (shapeFlag & ShapeFlags.STATEFULCOMPONENT) {
    processComponent(vnode, container)
  }
}

function processComponent(vnode, container) {
  mountComponent(vnode, container)
}

function mountComponent(initialVNode, container) {
  const instance = createComponentInstance(initialVNode)
  setupComponent(instance)
  setupRenderEffect(instance, initialVNode, container)
}
function setupRenderEffect(instance: any, initialVNode, container: any) {
  const { proxy } = instance
  const subTree = instance.render.call(proxy)

  patch(subTree, container)
  initialVNode.el = subTree.el
}
function processElement(vnode: any, container: any) {
  mountElement(vnode, container)
}

function mountElement(vnode: any, container: any) {
  const node = (vnode.el = document.createElement(vnode.type))
  const { props, children, shapeFlag } = vnode
  if (props) {
    for (const key in props) {
      const value = props[key]
      const isOn = /^on[A-Z]/.test(key)
      if (isOn) {
        node.addEventListener(key.slice(2).toLowerCase(), value)
      } else {
        node.setAttribute(key, value)
      }
    }
  }
  if (children) {
    // if (typeof children === 'string') {
    if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
      node.textContent = vnode.children
    } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
      mountChildren(vnode, node)
    }
  }
  container.append(node)
}

function mountChildren(vnode, container) {
  vnode.children.forEach((v) => {
    patch(v, container)
  })
}
